#ifndef REQUEST_H
#define REQUEST_H

#include <sys/types.h>

/*
 * Available request codes
 */
enum RequestCode
{
	DLM_LOCK,
	DLM_TRYLOCK,
	DLM_UNLOCK
};


/*
 * Available lock types
 */
enum LockType
{
	CR, // concurrent read
	CW, // concurrent write
	PR, // protected read
	PW, // protected write
	EX // exclusive
};


static const char* lockStrTab[] = { "CR", "CW", "PR", "PW", "EX" };


/*
 * Returns character representation of the lock (used for logging)
 */
static inline const char* lockStr(LockType lock)
{
	return lockStrTab[lock];
}


/*
 * Base request structure
 */
struct Request
{
	/*
	 * Constructor
	 * code		- request code
	 * pid		- pid of the process which sent the request
	 * res_id	- identification of the resource
	 */
	Request(RequestCode code, pid_t pid, int res_id) :
		code_((char)code), pid_(pid), resourceId_(res_id)
	{}
	
	char code_; // request code
	pid_t pid_; // process pid
	int resourceId_; // id of the resource
		
}__attribute__((packed));


/*
 * Lock request structure
 */
struct LockRequest : public Request
{
	/*
	 * Constructor
	 * pid		- pid of the process which sent the request
	 * res_id	- identification of the resource
	 * lock_type- which lock we request for
	 * timeout	- if greater than 0 it means we can wait for lock max timeout ms
	 */
	LockRequest(pid_t pid, int res_id, LockType lock_type, long timeout) :
		Request(DLM_LOCK, pid, res_id),
		lockType_((char)lock_type), timeout_(timeout)
	{}
	
	char lockType_;
	long timeout_;
	
}__attribute__((packed));


/*
 * TryLock request structure
 */
struct TryLockRequest : public Request
{
	/*
	 * Constructor
	 * pid		- pid of the process which sent the request
	 * res_id	- identification of the resource
	 * lock_type- which lock we want check
	 */
	TryLockRequest(pid_t pid, int resource_id, LockType lock_type) :
		Request(DLM_TRYLOCK, pid, resource_id),
		lockType_((char)lock_type)
	{}
	
	char lockType_;
	
}__attribute__((packed));


/*
 * UnLock request structure
 */
struct UnlockRequest : public Request
{
	/*
	 * Constructor
	 * pid		- pid of the process which sent the request
	 * res_id	- resource to unblock
	 */
	UnlockRequest(pid_t pid, int resource_id) :
		Request(DLM_UNLOCK, pid, resource_id)
	{}
	
}__attribute__((packed));


#endif
